package web.suzy.oj.manager.email;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.text.UnicodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import web.suzy.oj.config.NacosSwitchConfig;
import web.suzy.oj.config.WebConfig;
import web.suzy.oj.utils.Constants;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.Date;
import java.util.Properties;

/**
 * YangSuzy 软件工作室
 * 类名: EmailManager
 * 描述: 邮箱管理器
 * 功能: ---- 待定 -----
 *
 * @author YangSuzy
 * Date: 2022/11/13 22:31
 */
@Component
@RefreshScope //配置实例热加载
@Slf4j(topic = "suzyoj")
public class EmailManager {
    @Autowired
    private TemplateEngine templateEngine;

    @Autowired
    private NacosSwitchConfig nacosSwitchConfig;

    /**
     * 方法名: getMailSender
     * 描述: 获取邮箱系统配置
     *
     * @return org.springframework.mail.javamail.JavaMailSenderImpl
     * @date 2022/11/13 23:32
     * @auther YangSuzy
     **/
    private JavaMailSenderImpl getMailSender() {
        WebConfig webConfig = nacosSwitchConfig.getWebConfig();
        JavaMailSenderImpl sender = new JavaMailSenderImpl();
        //设置文字编码
        sender.setDefaultEncoding("UTF-8");
        //设置邮箱信息
        sender.setHost(webConfig.getEmailHost());
        sender.setPort(webConfig.getEmailPort());
        sender.setUsername(webConfig.getEmailUsername());
        sender.setPassword(webConfig.getEmailPassword());

        Properties p = new Properties();
        //开启SSL加密，否则报503错误
        p.setProperty("mail.smtp.ssl.enable", webConfig.getEmailSsl().toString());
        //发送服务器需要身份验证
        p.setProperty("mail.smtp.auth", "true");
        p.setProperty("mail.smtp.starttls.enable", webConfig.getEmailSsl().toString());
        //设置邮件协议对应465端口
        p.setProperty("mail.protocol", "smtps");
        sender.setJavaMailProperties(p);
        return sender;
    }

    /**
     * 方法名: isOk
     * 描述: 测试邮箱是否配置完成
     *
     * @return boolean
     * @date 2022/11/13 23:32
     * @auther YangSuzy
     **/
    public boolean isOk() {
        WebConfig webConfig = nacosSwitchConfig.getWebConfig();
        String host = webConfig.getEmailHost();
        Integer port = webConfig.getEmailPort();
        String username = webConfig.getEmailUsername();
        String password = webConfig.getEmailPassword();
        System.out.println("host:" + host);
        System.out.println("port:" + port);
        System.out.println("username:" + username);
        System.out.println("password:" + password);

        return webConfig.getEmailUsername() != null && webConfig.getEmailPassword() != null && "yangsuzy@qq.com".equals(webConfig.getEmailUsername()) && "wmvqykhgjyjxfdif".equals(webConfig.getEmailPassword()) && Validator.isEmail(webConfig.getEmailUsername());
    }

    /**
     * 方法名: sendCode
     * 描述: 为注册用户发送验证码
     *
     * @param email 注册用户邮箱
     * @param code  随机六位数字验证码
     * @return void
     * @date 2022/11/14 10:49
     * @auther YangSuzy
     **/
    @Async
    public void sendCode(String email, String code) {
        //设置10分钟后过期
        DateTime expireTime = DateUtil.offsetMinute(new Date(), 10);
        JavaMailSenderImpl mailSender = getMailSender();
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            //设置渲染到html页面对应的值
            Context context = new Context();
            WebConfig webConfig = nacosSwitchConfig.getWebConfig();
            context.setVariable(Constants.Email.OJ_NAME.name(), UnicodeUtil.toString(webConfig.getName()));
            context.setVariable(Constants.Email.OJ_SHORT_NAME.name(), UnicodeUtil.toString(webConfig.getShortName()));
            context.setVariable(Constants.Email.OJ_URL.name(), webConfig.getBaseUrl());
            //设置验证码
            context.setVariable("CODE", code);
            //设置过期时间
            context.setVariable("EXPIRE_TIME", expireTime.toString());

            //利用模板引擎加载html文件进行渲染并生成对应的字符串
            String emailContent = templateEngine.process("emailTemplate_registerCode", context);
            //邮件主题
            mimeMessageHelper.setSubject(UnicodeUtil.toString(webConfig.getShortName()) + "的注册邮件");
            //邮件内容
            mimeMessageHelper.setText(emailContent, true);
            //收件人
            mimeMessageHelper.setTo(email);
            //发送人
            mimeMessageHelper.setFrom(webConfig.getEmailUsername());
            mailSender.send(mimeMessage);
        } catch (MessagingException e) {
            log.error("用户注册的邮件任务发生异常------------>{}", e.getMessage());
        }
    }


    /**
     * 方法名: sendResetPassword
     * 描述: 发送重置密码链接
     *
     * @param username 需要重置密码的用户名
     * @param code     随机生成20位数字与字母的组合
     * @param email    用户邮箱
     * @return void
     * @date 2022/11/14 11:13
     * @auther YangSuzy
     **/
    @Async
    public void sendResetPassword(String username, String code, String email) {
        //设置10分钟后过期
        DateTime expireTime = DateUtil.offsetMinute(new Date(), 10);
        JavaMailSenderImpl mailSender = getMailSender();
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage,
                    true);
            //设置渲染到html页面对应的值
            Context context = new Context();
            WebConfig webConfig = nacosSwitchConfig.getWebConfig();
            context.setVariable(Constants.Email.OJ_NAME.name(), UnicodeUtil.toString(webConfig.getName()));
            context.setVariable(Constants.Email.OJ_SHORT_NAME.name(), UnicodeUtil.toString(webConfig.getShortName()));
            context.setVariable(Constants.Email.OJ_URL.name(), webConfig.getBaseUrl());

            //重置密码链接（暂时加上:8066端口号，后期去掉）
            String resetUrl;
            if (webConfig.getBaseUrl().endsWith("/")) {
                resetUrl = webConfig.getBaseUrl() + ":8066/reset-password?username=" + username + "&code=" + code;
            } else {
                resetUrl = webConfig.getBaseUrl() + ":8066/reset-password?username=" + username + "&code=" + code;
            }
            //设置重置密码链接和失效时间
            context.setVariable("RESET_URL", resetUrl);
            context.setVariable("EXPIRE_TIME", expireTime.toString());
            context.setVariable("USERNAME", username);

            //利用模板引擎加载html文件进行渲染并生成对应的字符串
            String emailContent = templateEngine.process("emailTemplate_resetPassword", context);
            //邮件主题
            mimeMessageHelper.setSubject(UnicodeUtil.toString(webConfig.getShortName()) + "的重置密码邮件");
            //邮件内容
            mimeMessageHelper.setText(emailContent, true);
            //收件人
            mimeMessageHelper.setTo(email);
            //发送人
            mimeMessageHelper.setFrom(webConfig.getEmailUsername());
            mailSender.send(mimeMessage);
        } catch (MessagingException e) {
            log.error("用户重置密码的邮件任务发生异常------------>{}", e.getMessage());
        }
    }

    /**
     * 方法名: testEmail
     * 描述: 测试邮箱方法
     *
     * @param email
     * @return void
     * @date 2022/11/13 23:03
     * @auther YangSuzy
     **/
    @Async
    public void testEmail(String email) {
        JavaMailSenderImpl mailSender = getMailSender();
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            //设置渲染到html页面对应的值
            Context context = new Context();
            WebConfig webConfig = nacosSwitchConfig.getWebConfig();
            context.setVariable(Constants.Email.OJ_NAME.name(), UnicodeUtil.toString(webConfig.getName()));
            context.setVariable(Constants.Email.OJ_SHORT_NAME.name(), UnicodeUtil.toString(webConfig.getShortName()));
            context.setVariable(Constants.Email.OJ_URL.name(), webConfig.getBaseUrl());
            context.setVariable(Constants.Email.EMAIL_BACKGROUND_IMG.name(), webConfig.getBaseUrl());
            //利用模板引擎加载html文件进行渲染并生成对应的字符串
            String emailContent = templateEngine.process("emailTemplate_testEmail", context);
            //邮件主题
            mimeMessageHelper.setSubject(UnicodeUtil.toString(webConfig.getShortName()) + "的测试邮件");
            //邮件内容
            mimeMessageHelper.setText(emailContent, true);
            //收件人
            mimeMessageHelper.setTo(email);
            //发送人
            mimeMessageHelper.setFrom(webConfig.getEmailUsername());
            mailSender.send(mimeMessage);
        } catch (MessagingException e) {
            log.error("超级管理员重置邮件系统配置的测试邮箱可用性的任务发生异常------------>{}", e.getMessage());
        }
    }

}
